#pragma once
#ifndef DllLoader_hpp
#define DllLoader_hpp

#include<string>
#include<filesystem>
#include"../Framework/DataTypeDef.hpp"

#ifdef WIN32
#include<windows.h>
#else 
#include<dlfcn.h>
#endif

#ifdef _MSC_VER
#define MMF_STD_CALL __stdcall
#define MMF_EXPORT _declspec(dllexport)
#else 
#define MMF_STD_CALL __attribute__((stdcall))
#define MMF_EXPORT
#endif


namespace MMF 
{

    struct DllLoader
    {
        static Handle LoadDLL(const std::string& pathName);
        static void CloseDLL(Handle hdl);

        template<typename FuncType>
        static FuncType GetFunc(Handle hdl, const std::string& funcName);

    };

    template<typename FuncType>
    FuncType DllLoader::GetFunc(Handle hdl, const std::string& funcName)
    {
        void* funcAdd = NULL;
        
    #ifdef WIN32
        funcAdd = ::GetProcAddress((::HMODULE)hdl, funcName.c_str());
    #else
        funcAdd = dlsym(hdl, funcName.c_str());
    #endif

        return FuncType(funcAdd);
    }
}



#endif